home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1993, 1994 Marc Parmet.
- * This file is part of the Macintosh port of GNU Emacs.
- *
- * GNU Emacs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
- #include <MacHeaders>
- #include <Folders.h>
- #include <Script.h>
- #include "getopt.h"
- #include "stdio.h"
-
- static char print_format,border_rect,need_page_setup;
- static ProcessSerialNumber psn;
-
- static int
- launch_daemon(int *we_started_it)
- {
- short err;
- FSSpec spec;
- LaunchParamBlockRec lpb;
-
- err = unixfn2FSSpec("/bin/Print Daemon",&spec,0);
- if (err) return err;
-
- lpb.launchBlockID = extendedBlock;
- lpb.launchEPBLength = extendedBlockLen;
- lpb.launchFileFlags = 0;
- lpb.launchControlFlags = launchContinue | launchNoFileFlags | launchDontSwitch;
- lpb.launchAppSpec = &spec;
- lpb.launchAppParameters = 0L;
-
- err = LaunchApplication(&lpb);
- psn = lpb.launchProcessSN;
- *we_started_it = (lpb.launchPreferredSize != 0);
- return err;
- }
-
- static void
- send_event(long class,long type,...)
- {
- short err;
- long *others,keyword;
- AEDesc target,*desc;
- AppleEvent event,reply;
- char have_target,have_event,have_reply;
-
- have_target = have_event = have_reply = 0;
-
- err = AECreateDesc(typeProcessSerialNumber,&psn,
- sizeof(ProcessSerialNumber),&target);
- if (err) goto bail;
- have_target = 1;
- err = AECreateAppleEvent(class,type,&target,
- kAutoGenerateReturnID,kAnyTransactionID,&event);
- if (err) goto bail;
- have_event = 1;
-
- others = &type+1;
- while (others[0] != 0) {
- desc = (AEDesc *)others[0];
- keyword = others[1];
- err = AEPutParamDesc(&event,keyword,desc);
- if (err) goto bail;
- others += 2;
- }
-
- // kAEWaitReply and kAESwitchLayer are both required to bring the printing
- // dialog box to the front immediately without using the notification manager.
- // An idle or filter proc here isn't really possible, because we don't have
- // direct access to the event handlers of Emacs.
- err = AESend(&event,&reply,kAEWaitReply | kAECanInteract | kAECanSwitchLayer,
- kAENormalPriority,kAEDefaultTimeout,0,0);
- if (err) goto bail;
- have_reply = 1;
-
- bail:
- if (have_target) AEDisposeDesc(&target);
- if (have_event) AEDisposeDesc(&event);
- if (have_reply) AEDisposeDesc(&reply);
- return;
- }
-
- static void
- kill_daemon(void)
- {
- send_event(kCoreEventClass,kAEQuitApplication,0);
- }
-
- static void
- print_file(FSSpec *spec)
- {
- short err;
- AEDesc desc;
-
- err = AECreateDesc(typeFSS,spec,sizeof(FSSpec),&desc);
- if (err) return;
- send_event(kCoreEventClass,kAEPrintDocuments,&desc,keyDirectObject,0);
- AEDisposeDesc(&desc);
- }
-
- static void
- reset_options(void)
- {
- send_event('EMAC','rset',0);
- }
-
- static void
- send_option(char *name,...)
- {
- short err;
- AEDescList list;
-
- err = AECreateList(0L,0,0,&list);
- if (err) return;
- err = AEPutPtr(&list,0,typeChar,name,strlen(name));
- if (err) goto bail;
-
- if (!strcmp(name,"p") || !strcmp(name,"R")) {
- Boolean k = ((int *)&name)[1];
- err = AEPutPtr(&list,0,typeBoolean,&k,sizeof(k));
- if (err) goto bail;
- }
-
- send_event('EMAC','opts',&list,keyDirectObject,0);
-
- bail:
- AEDisposeDesc(&list);
- return;
- }
-
- static void
- do_page_setup(void)
- {
- send_event('EMAC','pgst',0);
- }
-
- static int
- copy_stdin_to_tempfile(FSSpec *spec,int *filelen)
- {
- int fd;
- long n;
- char p[256];
- short err,refNum;
-
- err = FindFolder(kOnSystemDisk,kTemporaryFolderType,kCreateFolder,
- &spec->vRefNum,&spec->parID);
- if (err) return err;
- pstrcpy(spec->name,"\plpr standard input");
- err = FSpCreate(spec,'EMAC','TEXT',smSystemScript);
- if (err && err != dupFNErr) return err;
- err = FSpOpenDF(spec,fsWrPerm,&refNum);
- if (err) { FSpDelete(spec); return err; }
- err = SetEOF(refNum,0);
- if (err) { FSpDelete(spec); return err; }
-
- *filelen = 0;
- fd = fileno(stdin);
- while (1) {
- n = read(fd,p,sizeof(p));
- if (n == 0) break;
- if (n == -1) { FSClose(refNum); FSpDelete(spec); return err; }
- err = FSWrite(refNum,&n,&p);
- if (err) { FSClose(refNum); FSpDelete(spec); return err; }
- *filelen += n;
- }
-
- FSClose(refNum);
- return noErr;
- }
-
- int
- main(int argc,char **argv)
- {
- int c,k,stdin_len;
- char *fname;
- int err;
- FSSpec spec;
- int we_started_it;
- int retcode = 0;
-
- err = launch_daemon(&we_started_it);
- if (err) return err;
-
- while (1) {
- c = getopt(argc,argv,"pRP");
- if (c == EOF) break;
- switch (c) {
- case 'p': print_format = 1; break;
- case 'R': border_rect = 1; break;
- case 'P': need_page_setup = 1; break;
- }
- }
-
- if (need_page_setup) do_page_setup();
- reset_options();
- send_option("p",print_format);
- send_option("R",border_rect);
-
- k = optind;
-
- if (k == argc) {
- copy_stdin_to_tempfile(&spec,&stdin_len);
- if (stdin_len == 0) {
- fprintf(stderr,"%s: Nothing to print\n",argv[0]);
- retcode = 1;
- }
- else
- print_file(&spec);
- FSpDelete(&spec);
- }
- else {
- for (; k<argc; ++k) {
- fname = argv[k];
- err = unixfn2FSSpec(fname,&spec,0);
- if (err)
- fprintf(stderr,"%s: cannot open file '%s'\n",argv[0],fname);
- else
- print_file(&spec);
- }
- }
-
- if (we_started_it) kill_daemon();
- return retcode;
- }
-